package com.fx.device.service.activit.impl;

import com.fx.device.common.util.ErrorEnum;
import com.fx.device.common.util.ReturnMessage;
import com.fx.device.common.util.ReturnMessageUtils;
import com.fx.device.common.util.SecurityUtil;
import com.fx.device.service.activit.ProcessInstanceService;
import com.fx.device.vo.activit.ProUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ProcessInstanceServiceImpl implements ProcessInstanceService {


    final private ProcessRuntime processRuntime;


    final private SecurityUtil securityUtil;


    final private RepositoryService repositoryService;


    @Override
    public ReturnMessage<Object> getInstances(ProUser proUser, int page, int size) {
        Page<ProcessInstance> processInstances = null;
        try {

            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("wukong");
            }
            //else {
            //  securityUtil.logInAs(proUser.getUsername());//这句不需要,如果业务需要反馈可以获取登录用户数据
            // }
            processInstances = processRuntime.processInstances(Pageable.of(page, size));
            //System.out.println("流程实例数量： " + processInstances.getTotalItems());
            List<ProcessInstance> list = processInstances.getContent();
            //list.sort((y,x)->x.getProcessDefinitionVersion()-y.getProcessDefinitionVersion());
            //排序
            list.sort((y, x) -> x.getStartDate().toString().compareTo(y.getStartDate().toString()));

            List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>();
            for (ProcessInstance pi : list) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("id", pi.getId());
                hashMap.put("name", pi.getName());
                hashMap.put("status", pi.getStatus());
                hashMap.put("processDefinitionId", pi.getProcessDefinitionId());
                hashMap.put("processDefinitionKey", pi.getProcessDefinitionKey());
                hashMap.put("startDate", pi.getStartDate());
                hashMap.put("processDefinitionVersion", pi.getProcessDefinitionVersion());
                //因为processRuntime.processDefinition("流程部署ID")查询的结果没有部署流程与部署ID，所以用repositoryService查询,此处需要优化
                ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                        .processDefinitionId(pi.getProcessDefinitionId())
                        .singleResult();
                hashMap.put("resourceName", pd.getResourceName());
                hashMap.put("deploymentId", pd.getDeploymentId());
                listMap.add(hashMap);
            }

            return ReturnMessageUtils.success(listMap);
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_GET.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_GET.getErrorMsg(), e.toString());
        }
    }

    @Override
    public ReturnMessage<Object> startProcess(String processDefinitionKey, String instanceName) {
        try {
            //谁登录谁去执行实例
            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("huangyang");
            } else {
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
                    .start()
                    .withProcessDefinitionKey(processDefinitionKey)
                    .withName(instanceName)
                    //.withVariable("content", instanceVariable)
                    //.withVariable("参数2", "参数2的值")
                    .withBusinessKey("自定义BusinessKey")
                    .build());
            return ReturnMessageUtils.success(processInstance.getName() + "；" + processInstance.getId());
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_GREAT.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_GREAT.getErrorMsg(), e.toString());
        }
    }

    @Override
    public ReturnMessage<Object> startProcessWithVar(String processDefinitionKey, String instanceName, String instanceVariable) {
        try {
            //谁登录谁去执行实例
            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("huangyang");
            } else {
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
                    .start()
                    .withProcessDefinitionKey(processDefinitionKey)
                    .withName(instanceName)
                    .withVariable("content", instanceVariable)
                    //.withVariable("参数2", "参数2的值")
                    .withBusinessKey("自定义BusinessKey")
                    .build());
            return ReturnMessageUtils.success(processInstance.getName() + "；" + processInstance.getId());
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_GREAT.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_GREAT.getErrorMsg(), e.toString());
        }
    }

    @Override
    public ReturnMessage<Object> deleteInstance(String instanceID) {
        try {
            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("wukong");
            }

            ProcessInstance processInstance = processRuntime.delete(ProcessPayloadBuilder
                    .delete()
                    .withProcessInstanceId(instanceID)
                    .build()
            );
            return ReturnMessageUtils.success(processInstance.getName());
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_DEL.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_DEL.getErrorMsg(), e.toString());
        }
    }

    @Override
    public ReturnMessage<Object> suspendInstance(String instanceID) {
        try {
            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("wukong");
            }

            ProcessInstance processInstance = processRuntime.suspend(ProcessPayloadBuilder
                    .suspend()
                    .withProcessInstanceId(instanceID)
                    .build()
            );
            return ReturnMessageUtils.success(processInstance.getName());
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_SUSPEN.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_SUSPEN.getErrorMsg(), e.toString());
        }
    }

    @Override
    public ReturnMessage<Object> resumeInstance(String instanceID) {
        try {
            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("wukong");
            }

            ProcessInstance processInstance = processRuntime.resume(ProcessPayloadBuilder
                    .resume()
                    .withProcessInstanceId(instanceID)
                    .build()
            );
            return ReturnMessageUtils.success(processInstance.getName());
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_RESUME.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_RESUME.getErrorMsg(), e.toString());
        }
    }

    @Override
    public ReturnMessage<Object> variables(String instanceID) {
        try {
            if (ReturnMessageUtils.Test) {
                securityUtil.logInAs("wukong");
            }
            List<VariableInstance> variableInstance = processRuntime.variables(ProcessPayloadBuilder
                    .variables()
                    .withProcessInstanceId(instanceID)
                    .build());

            return ReturnMessageUtils.success(variableInstance);
        } catch (Exception e) {
            return ReturnMessageUtils.error(ErrorEnum.E_ACTIVIT_PROCINSTID_VARIABLES.getErrorCode(),
                    ErrorEnum.E_ACTIVIT_PROCINSTID_VARIABLES.getErrorMsg(), e.toString());
        }
    }


}
